package net.pinnoocle.playservice.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import net.pinnoocle.playcommon.exception.ShopException;
import net.pinnoocle.playcommon.response.ErrorCode;
import net.pinnoocle.playcommon.utils.ConvertUtils;
import net.pinnoocle.playcommon.utils.HelpUtils;
import net.pinnoocle.playdao.dao.CouponDao;
import net.pinnoocle.playdao.entity.Coupon;
import net.pinnoocle.playdao.entity.UserCoupon;
import net.pinnoocle.playdao.entity.page.PageModel;
import net.pinnoocle.playdao.entity.page.PageQuery;
import net.pinnoocle.playdao.entity.shopPc.coupon.CouponListPageVo;
import net.pinnoocle.playdao.entity.shopPc.coupon.CouponListSearchParams;
import net.pinnoocle.playdao.entity.shopPc.coupon.SaveCouponParams;
import net.pinnoocle.playdao.entity.web.user.UserCouponListPageVo;
import net.pinnoocle.playdao.entity.web.user.UserCouponListSearchParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 优惠券(Coupon)表服务实现类
 *
 * @author ye
 * @since 2021-10-28 18:35:17
 */
@Service("couponService")
@Slf4j
public class CouponServiceImpl extends ServiceImpl<CouponDao, Coupon> {

    @Autowired
    ShopServiceImpl shopService;
    @Autowired
    UserCouponServiceImpl userCouponService;
    @Autowired
    UserServiceImpl userService;

    /**
     * 优惠券列表
     * @param searchParams
     * @return
     */
    public PageModel<CouponListPageVo> couponList(CouponListSearchParams searchParams){

        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(searchParams.getPage()));
        pageMap.put("pageSize",String.valueOf(searchParams.getPageSize()));

        if(searchParams.getShopId() == null){
            searchParams.setShopId(userService.getGlobalShopId());
        }
        String userId = userService.getUserId();
        Page<CouponListPageVo> list = this.baseMapper.couponList(
                new PageQuery<Coupon>(pageMap).getPage(),searchParams);
        List<CouponListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        for (CouponListPageVo item : records){
            UserCoupon userCoupon = this.baseMapper.findUserCoupon(item.getCouponId(), userId);
            if(Objects.isNull(userCoupon)){
                item.setUserCouponId(null);
            }else{
                item.setUserCouponId(userCoupon.getUserCouponId());
            }
        }
        return new PageModel<>(list, records);
    }


    /**
     * 用户优惠券列表
     * @param searchParams
     * @return
     */
    public PageModel<UserCouponListPageVo> userCouponList(UserCouponListSearchParams searchParams){

        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("page",String.valueOf(searchParams.getPage()));
        pageMap.put("pageSize",String.valueOf(searchParams.getPageSize()));

        if(searchParams.getShopId() == null){
            searchParams.setShopId(userService.getGlobalShopId());
        }
        searchParams.setUserId(userService.getUserId());
        Page<UserCouponListPageVo> list = this.baseMapper.userCouponList(
                new PageQuery<UserCoupon>(pageMap).getPage(),searchParams);
        List<UserCouponListPageVo> records = list.getRecords();
        if (CollectionUtils.isEmpty(records)) {
            return new PageModel<>(list, new ArrayList<>());
        }
        return new PageModel<>(list, records);
    }

    /**
     * 用户领取优惠券
     * @param couponId
     * @return
     */
    public boolean receiveCoupon(String couponId){
        Coupon baseCoupon = this.getById(couponId);
        if(Objects.isNull(baseCoupon)){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"优惠券不存在");
        }
        String userId = userService.getUserId();
        int receiveTimes = userCouponService.count(new QueryWrapper<UserCoupon>().lambda()
                .eq(UserCoupon::getBaseCouponId, couponId)
                .eq(UserCoupon::getUserId, userId));
        if(receiveTimes > 0){
            throw new ShopException(ErrorCode.PARAMS_GET_ERROR,"重复领取");
        }
        try {
            UserCoupon userCoupon = ConvertUtils.sourceToTarget(baseCoupon, UserCoupon.class);
            userCoupon.setUserId(userId);
            int couponStatus = getCouponStatus(baseCoupon.getValidStartDate(), baseCoupon.getValidEndDate());
            userCoupon.setEffectStatus(couponStatus);
            userCoupon.setCreatedTime(new Date());
            userCoupon.setBaseCouponId(couponId);
            return userCouponService.save(userCoupon);
        } catch (Exception e) {
            log.info("用户领取优惠券失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 添加优惠券
     * @param params
     * @return
     */
    public boolean createCoupon(SaveCouponParams params){
        String shopId = shopService.getShopId();
        try {
            Coupon coupon = ConvertUtils.sourceToTarget(params, Coupon.class);
            coupon.setCreatedTime(new Date());
            coupon.setShopId(shopId);
            int couponStatus = getCouponStatus(params.getValidStartDate(), params.getValidEndDate());
            coupon.setEffectStatus(couponStatus);
            return this.save(coupon);
        } catch (Exception e) {
            log.info("添加优惠券失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 编辑优惠券
     * @param params
     * @return
     */
    public boolean updateCoupon(SaveCouponParams params){
        try {
            Coupon coupon = ConvertUtils.sourceToTarget(params, Coupon.class);
            int couponStatus = getCouponStatus(params.getValidStartDate(), params.getValidEndDate());
            coupon.setEffectStatus(couponStatus);
            return this.updateById(coupon);
        } catch (Exception e) {
            log.info("编辑优惠券失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 删除优惠券
     * @param couponId
     * @return
     */
    public boolean deleteCoupon(String couponId){
        try {
            return this.removeById(couponId);
        } catch (Exception e) {
            log.info("删除优惠券失败："+e.getMessage());
        }
        return false;
    }

    /**
     * 获取优惠券生效状态
     * @param couponSValidStartDate
     * @param couponValidEndDate
     * @return
     */
    public int getCouponStatus(String couponSValidStartDate,String couponValidEndDate){
        Date startDate = DateUtil.parse(couponSValidStartDate+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
        Date endDate = DateUtil.parse(couponValidEndDate+" 23:59:59", "yyyy-MM-dd HH:mm:ss");
        boolean isStart = HelpUtils.compareDateToNow(startDate);
        boolean isEnd = HelpUtils.compareDateToNow(endDate);
        if(isStart && !isEnd){
            return 1;
        }else if(isEnd){
            return 2;
        }
        return 0;
    }

    /**
     * 异步修改优惠券的生效状态
     */
    public void changeCoupon(){
        List<Coupon> couponList = this.list(new QueryWrapper<Coupon>()
                .lambda()
                .eq(Coupon::getIsDisable, 0)
                .ne(Coupon::getEffectStatus,2));
        for (Coupon coupon : couponList){
            Date startDate = DateUtil.parse(coupon.getValidStartDate()+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
            Date endDate = DateUtil.parse(coupon.getValidEndDate()+" 23:59:59", "yyyy-MM-dd HH:mm:ss");
            boolean isStart = HelpUtils.compareDateToNow(startDate);
            boolean isEnd = HelpUtils.compareDateToNow(endDate);
            //生效
            if(isStart && !isEnd){
                this.baseMapper.changeCouponStatus(coupon.getCouponId(),1);
            }else if(isEnd){
                this.baseMapper.changeCouponStatus(coupon.getCouponId(),2);
            }
        }
    }

    /**
     * 异步修改用户优惠券生效状态
     */
    public void changeUserCoupon(){
        //过滤已过期的
        List<UserCoupon> userCouponList = userCouponService.list(new QueryWrapper<UserCoupon>()
                .lambda()
                .ne(UserCoupon::getStatus, 2));
        for (UserCoupon coupon : userCouponList){
            Date startDate = DateUtil.parse(coupon.getValidStartDate()+" 00:00:00", "yyyy-MM-dd HH:mm:ss");
            Date endDate = DateUtil.parse(coupon.getValidEndDate()+" 23:59:59", "yyyy-MM-dd HH:mm:ss");
            boolean isStart = HelpUtils.compareDateToNow(startDate);
            boolean isEnd = HelpUtils.compareDateToNow(endDate);
            //生效
            if(isStart && !isEnd){
                this.baseMapper.changeUserCouponStatus(coupon.getUserCouponId(),1);
                //失效
            }else if(isEnd){
                this.baseMapper.changeCouponStatus(coupon.getUserCouponId(),2);
            }
        }
    }
}